

float4 DiffuseColor;
float3 AmbientColor;			
float4 SpecularColor;
float HeightScale;


float3 CameraPosition;
float3 LightDir;


Texture2D DiffuseTexture : register(s0);
sampler2D Diffuse = 
sampler_state
{
    Texture = < DiffuseTexture >;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

Texture2D NormalHeightmapTexture : register(s1);
sampler2D NormalHeightMap = 
sampler_state
{
    Texture = < NormalHeightmapTexture >;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

// Structs




struct PS_INPUT
{ 
float4 position          : POSITION;
	float3 positionWS :TEXCOORD6;
   float2 texCoord          : TEXCOORD0;
   float3 vLightTS          : TEXCOORD1;   // light vector in tangent space, denormalized
   float3 vViewTS           : TEXCOORD2;   // view vector in tangent space, denormalized
   float2 vParallaxOffsetTS : TEXCOORD3;   // Parallax offset vector in tangent space
   float3 vNormalWS         : TEXCOORD4;   // Normal vector in world space
   float3 vViewWS           : TEXCOORD5;   // View vector in world space
	float3 tangentWS         :COLOR0;
	float3 binormalWS		:COLOR1;	
};


float4 ComputeIllumination( float2 texCoord, PS_INPUT i, float fOcclusionShadow )
{
   // Sample the normal from the normal map for the given texture sample:
   float3 vNormalTS = normalize( tex2D( NormalHeightMap, texCoord ) ).rgb ;
   
   // Sample base map:
   float4 cBaseColor = tex2D( Diffuse, texCoord );

   float3 normalW = i.vNormalWS;
   float3x3 bumpMatrix;
	bumpMatrix[0] = i.tangentWS;
	bumpMatrix[1] = i.binormalWS;
	bumpMatrix[2] = normalW;

   normalW = normalize(normalW + mul(vNormalTS, bumpMatrix));
  
   float3 diffuseAmount = saturate(dot(normalW, -LightDir)) * DiffuseColor.rgb;

   float3 posToEye = normalize(CameraPosition - i.positionWS);
   float3 halfToLight = normalize(posToEye - LightDir);

   float3 specularAmount = pow(saturate(dot(normalW, halfToLight)),SpecularColor.a) * SpecularColor.rgb;
   
   // Composite the final color:
   float4 cFinalColor = float4((( AmbientColor + diffuseAmount ) * cBaseColor.rgb + specularAmount ) * fOcclusionShadow, cBaseColor.a * DiffuseColor.a); 
   
   return cFinalColor;  
}  

// Shaders
float4 main(PS_INPUT i) : COLOR
{
	const float sfHeightBias = 0.01;
   
   //  Normalize the interpolated vectors:
   float3 vViewTS   = normalize( i.vViewTS  );
   float3 vLightTS  = normalize( i.vLightTS );
   
   // Sample the height map at the current texture coordinate:
   float fCurrentHeight = tex2D( NormalHeightMap, i.texCoord ).a;
   
   // Scale and bias this height map value:
   float fHeight = fCurrentHeight * HeightScale + sfHeightBias;
   
   // Perform offset limiting if desired:
   fHeight /= vViewTS.z;
   
   // Compute the offset vector for approximating parallax:
   float2 texSample = i.texCoord + vViewTS.xy * fHeight;
   
   float4 cResultColor = float4( 0, 0, 0, 1 );

   // Compute resulting color for the pixel:
   cResultColor = ComputeIllumination( texSample, i, 1.0f );
         
   // If using HDR rendering, make sure to tonemap the resuld color prior to outputting it.
   // But since this example isn't doing that, we just output the computed result color here:
   return cResultColor;
}